package org.vectrics.dataweb;

import java.util.Locale;

import org.apache.log4j.Logger;
import org.vectrics.VectricsException;
import org.vectrics.struts.Request;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;


abstract public class WebServiceAction implements WebService {
	protected transient Logger log = Logger.getLogger(this.getClass());
	private Locale locale = null;
	
	/* (non-Javadoc)
	 * @see org.vectrics.dataweb.WebService#getLocale()
	 */
	public Locale getLocale() {
		return(locale);
	}

	/**
	 * 
	 */
	public WebServiceAction() {
		super();
	}
	
	/* (non-Javadoc)
	 * @see org.vectrics.dataweb.WebService#getData(org.vectrics.struts.Request, java.lang.String, org.w3c.dom.Element, org.w3c.dom.Element)
	 */
	abstract public void getData(Request request, String command, Element requestElement, 
				Element responseElement);

	/**
	 * find or create child element.
	 * @param parent
	 * @param childNodeName
	 * @return
	 */
	protected Element createChildElement(Element parent, String childNodeName) {
		Element childElement = null;
		childElement = parent.getOwnerDocument().createElement(childNodeName);
		parent.appendChild(childElement);
		return(childElement);
	}

	protected Element getCreateChildElement(Element parent, String childNodeName) {
		NodeList nodes = parent.getElementsByTagName(childNodeName);
		
		Element childElement = null;
		if (nodes.getLength() > 0) {
			childElement = (Element)nodes.item(0);
		} else {
			childElement = parent.getOwnerDocument().createElement(childNodeName);
			parent.appendChild(childElement);
		}
		return(childElement);
	}
	
	/* (non-Javadoc)
	 * @see org.vectrics.dataweb.WebService#processRequest(org.vectrics.struts.Request, java.lang.String, org.w3c.dom.Element, org.w3c.dom.Element)
	 */
	public void processRequest(Request request, String command, 
			Element requestDataElement, Element responseElement)
				throws VectricsException {
		log.debug("processRequest(request) - called");
		this.locale = request.getLocale();

		Element responseDataElement = this.createChildElement(responseElement,  "data");
		responseElement.appendChild(responseDataElement);

		try {
			log.debug("processRequest(request) - getting data from derived class "
					+ "- request data provided");
			Element rootElement = responseElement;
			Document responseDocument = responseElement.getOwnerDocument();
			processData(request, command, requestDataElement, responseDataElement);
		}
		catch (Exception ve) {
			log.error("VectricException processing response", ve);
			Element errorElement = this.createChildElement(responseElement, "error");
			errorElement.setAttribute("message", "Exception processing response: " + ve.getMessage());
			errorElement.setAttribute("code", "exception");
		}
	}
	
	/* (non-Javadoc)
	 * @see org.vectrics.dataweb.WebService#getDataElement(org.w3c.dom.Element)
	 */
	public Element getDataElement(Element responseElement) {
		Element dataElement = this.getCreateChildElement(responseElement, "data");
		return(dataElement);
	}
	
	
	protected final void processData(Request request, String command, Element requestDataElement,	
				Element responseElement) {
		log.info("Processing data, action class: " + this.getClass().getName());
		this.getData(request, command, requestDataElement, responseElement);
	}
	
}
